package me.zhengjie.modules.other.rest;

import com.github.utils.DateUtils;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.service.other.domain.*;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.other.service.dto.*;
import com.qiaofang.applet.service.other.service.mapstruct.CorporationMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.modules.member.vo.CorporationReportVo;
import me.zhengjie.modules.other.service.dto.CityCompanyQuery;
import me.zhengjie.modules.other.service.dto.CorporationSimpleDto;
import me.zhengjie.modules.other.service.dto.LogoConfigDto;
import me.zhengjie.modules.other.service.dto.SwitchConfigDto;
import me.zhengjie.utils.DateUtil;
import me.zhengjie.utils.ExcelUtil;
import me.zhengjie.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import static org.springframework.data.domain.Sort.Direction.ASC;

/**
 * Created by IDEA.
 *
 * @author QF2019
 * @company qiaofang
 * @date 2020/9/12 11:35
 */
@RestController
@RequiredArgsConstructor
@Api(tags = "小程序：集团管理")
@RequestMapping("/api/corporation")
@Slf4j
public class CorporationController {

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private CorporationMapper corporationMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @ApiOperation("集团列表")
    @GetMapping
    public ResponseEntity<Page<CorporationResponseDto>> list(CorporationRequestDto corporationRequestDto, Pageable pageable) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("corporationCode", match -> match.contains())
                .withMatcher("corporationName", match -> match.contains())
                .withMatcher("deleted", match -> match.exact())
                .withIgnoreNullValues();
        Corporation corporation = new Corporation();
        corporation.setCorporationCode(corporationRequestDto.getCorporationCode());
        corporation.setCorporationName(corporationRequestDto.getCorporationName());
        corporation.setDeleted(Boolean.FALSE);
        Page<Corporation> result = corporationService.findAll(Example.of(corporation, matcher), pageable);
        return ResponseEntity.ok(result.map(corporationMapper::toDto));
    }

    @PostMapping
    @ApiOperation("新增集团信息")
    public ResponseEntity<Object> create(@Validated @RequestBody Corporation corporation){
        corporation.setDeleted(Boolean.FALSE);
        SwitchConfig switchConfig = new SwitchConfig();
        switchConfig.setBoxUtil005("关闭");
        switchConfig.setBoxUtil006("关闭");
        switchConfig.setBoxUtil007("关闭");
        switchConfig.setBoxUtil008("关闭");
        switchConfig.setChocolate("关闭");
        switchConfig.setEDeals("关闭");
        switchConfig.setCommerceAcademy("关闭");
        corporation.setSwitchConfig(switchConfig);
        corporationService.saveCorporation(corporation);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PutMapping
    @ApiOperation("修改集团信息")
    public ResponseEntity<Object> update(@RequestBody Corporation corporation){
        corporation.setDeleted(false);
        corporationService.saveCorporation(corporation);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @ApiOperation("移除集团")
    @DeleteMapping
    public ResponseEntity<Object> remove(@RequestBody List<String> ids) {
        if(!CollectionUtils.isEmpty(ids)){
            corporationService.removeCorporation(ids.get(0));
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("保存短信配置")
    @PostMapping("saveSmsPlatformConfig")
    public ResponseEntity<Object> saveSmsPlatformConfig(@Validated @RequestBody SmsPlatformConfigDto smsPlatformConfig){
        Optional<Corporation> optional = corporationService.findById(smsPlatformConfig.getId());
        Corporation corporation = optional.get();
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }

        corporation.setSmsPlatformConfig(Arrays.asList(smsPlatformConfig));
        corporationService.save(corporation);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("保存功能开关配置")
    @PostMapping("saveSwitchConfig")
    public ResponseEntity<Object> saveSwitchConfig(@Validated @RequestBody SwitchConfigDto switchConfigDto){
        Optional<Corporation> optional = corporationService.findById(switchConfigDto.getId());
        Corporation corporation = optional.get();
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }

        corporation.setSwitchConfig(switchConfigDto);
        corporationService.save(corporation);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("保存Logo配置")
    @PostMapping("saveLogoConfig")
    public ResponseEntity<Object> saveLogoConfig(@Validated @RequestBody LogoConfigDto logoConfigDto){
        Optional<Corporation> optional = corporationService.findById(logoConfigDto.getId());
        Corporation corporation = optional.get();
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }

        corporation.setHomeLogo(logoConfigDto.getHomeLogo());
        corporation.setLogo(logoConfigDto.getLogo());
        corporation.setQrCode(logoConfigDto.getQrCode());
        corporation.setPcWebImg(logoConfigDto.getPcWebImg());
        corporation.setPcWebLogo(logoConfigDto.getPcWebLogo());
        corporation.setUpdateTime(new Date());
        corporationService.save(corporation);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("保存百度搜索引擎收录配置")
    @PostMapping("saveBaiduSearchConfig")
    public ResponseEntity<Object> saveBaiduSearchConfig(@Validated @RequestBody BaiduSearchEngineDto searchEngineDto){
        Optional<Corporation> optional = corporationService.findById(searchEngineDto.getId());
        Corporation corporation = optional.get();
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }
        corporation.setBaiduSearchEngine(new BaiduSearchEngine(searchEngineDto.getApiUrl(), searchEngineDto.getToken()));
        corporationService.save(corporation);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("隐私协议重置")
    @PostMapping("initPrivacyAgreement")
    public ResponseEntity<Object> initPrivacyAgreement(@Validated @RequestBody CityCompanyQuery cityCompanyQuery){
        Corporation corporation = corporationService.getCorporationByCorporationCode(cityCompanyQuery.getCorporationCode());
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }
        if (StringUtils.isNotBlank(corporation.getCorporationName())
                && StringUtils.isNotBlank(corporation.getNavigationBarTitle())){
            corporationService.initCorporationPrivacyAgreement(corporation);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("获取二手房上下架规则")
    @PostMapping("getPropertyRules")
    public ResponseEntity<PropertyRules> getPropertyRules(){
        return ResponseEntity.ok(corporationService.getPropertyRules(SecurityUtils.getCorporationCode()));
    }

    @ApiOperation("获取新房上下架规则")
    @PostMapping("getFirsthandRules")
    public ResponseEntity<FirsthandRules> getFirsthandRules(){
        return ResponseEntity.ok(corporationService.getFirsthandRules(SecurityUtils.getCorporationCode()));
    }

    @ApiOperation("保存二手房上下架规则")
    @PostMapping("savePropertyRules")
    public ResponseEntity<Object> savePropertyRules(@Validated @RequestBody PropertyRules propertyRules){
        corporationService.updatePropertyRules(SecurityUtils.getCorporationCode(), propertyRules);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("保存新房上下架规则")
    @PostMapping("saveFirsthandRules")
    public ResponseEntity<Object> saveFirsthandRules(@Validated @RequestBody FirsthandRules firsthandRules){
        corporationService.updateFirsthandRules(SecurityUtils.getCorporationCode(), firsthandRules);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("修改集团字典增量数据")
    @PostMapping("incrementAddToDict")
    public ResponseEntity<Object> incrementAddToDict() {
        corporationService.incrementAddToDict();
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("获取经纪人标签列表")
    @PostMapping(value = "/getEmployeeLabelList")
    public ResponseEntity<Object> getEmployeeLabelList(){
        String corporationCode = SecurityUtils.getCorporationCode();
        return ResponseEntity.ok(corporationService.getEmployeeLabelList(corporationCode));
    }

    @ApiOperation("官网隐私协议重置")
    @PostMapping("initPCPrivacyAgreement")
    public ResponseEntity<Object> initPCPrivacyAgreement(@Validated @RequestBody CityCompanyQuery cityCompanyQuery){
        Corporation corporation = corporationService.getCorporationByCorporationCode(cityCompanyQuery.getCorporationCode());
        if(corporation == null) {
            throw new BusinessException("未找到对应的集团信息");
        }
        if (StringUtils.isNotBlank(corporation.getCorporationName())
                && StringUtils.isNotBlank(corporation.getNavigationBarTitle())){
            corporationService.initCorporationPCPrivacyAgreement(corporation);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("获取集团列表")
    @PostMapping(value = "/getCorpList")
    public ResponseEntity<List<CorporationSimpleDto>> getCorpList(){
        Criteria criteria = Criteria.where("deleted").is(Boolean.FALSE);
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("corporationCode")
                        .first("corporationCode").as("corporationCode")
                        .first("corporationName").as("corporationName"),
                Aggregation.sort(ASC, "corporationName")
        );

        AggregationResults result = mongoTemplate.aggregate(agg, "other_corporation", CorporationSimpleDto.class);
        return ResponseEntity.ok(result.getMappedResults());
    }

    @GetMapping("/exportStatistics")
    @ApiOperation("导出集团全量统计数据")
    @AnonymousAccess
    public void exportExcel(HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
        List<CorporationReportVo> reportVos = new LinkedList<>();
        String name = "小程序集团全量数据统计" + DateUtils.date2Str(new Date() ,"yyyyMMdd_HHmm") + ".xlsx";
        String userAgent = request.getHeader("User-Agent");
        byte[] bytes = userAgent.contains("MSIE") ? name.getBytes() : name.getBytes("UTF-8"); // name.getBytes("UTF-8")处理safari的乱码问题  
        name = new String(bytes, "ISO-8859-1"); // 各浏览器基本都支持ISO编码  
        response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", name));
        response.setHeader("Content-Disposition", "attachment;filename=" + name);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/OCTET-STREAM;charset=UTF-8");

        List<CorporationReportDto> reportList = corporationService.getCorporationReportList();
        if (!CollectionUtils.isEmpty(reportList)) {
            for (CorporationReportDto src : reportList) {
                CorporationReportVo target = new CorporationReportVo();
                BeanUtils.copyProperties(src, target);
                reportVos.add(target);
            }
        }

        ExcelUtil<CorporationReportVo> util = new ExcelUtil<>(CorporationReportVo.class);
        try {
            util.exportExcel(reportVos, "集团统计列表", 65536, response.getOutputStream());
        } catch (IOException e) {
            log.info("导出集团统计数据表格失败", e);
        }
    }
}
